package com.factory.rest.controller;

import com.factory.common.bean.BaseBean;
import com.factory.common.bean.User;
import com.factory.common.core.SqlCondition;
import com.factory.common.core.ValidateType;
import com.factory.common.pojo.QueryListParam;
import com.factory.common.pojo.Result;
import com.factory.rest.feign.BaseFeignClient;
import com.factory.rest.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;
import java.util.Optional;

/**
 * 基础的远程调用控制器
 *
 * @author JW
 * @version 1.0
 * @date 2020/10/28 9:56
 */
public abstract class BaseFeignController<T extends BaseBean> {

    protected static final Logger log = LoggerFactory.getLogger(BaseFeignController.class);

    protected abstract BaseFeignClient getBaseFeignClient();

    @Autowired
    private UserService userService;

    protected User getUser() {
        return userService.getLoginUser().get();
    }

    /**
     * T
     * 通用的添加方法
     *
     * @return 用户列表
     */

    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    public Result insert(@RequestBody T t) {
        log.info("通用的添加数据方法,{}", t);
        if (t == null) {
            return Result.fail(500, "request body can not null!");
        }

        Optional<User> loginUser = userService.getLoginUser();
        if (loginUser.isPresent()) {
            User user = loginUser.get();
            t.setUser(user);
        }

        //校验
        Optional<Result> validate = t.validate(ValidateType.INSERT);
        if (validate.isPresent()) {
            return validate.get();
        }

        return getBaseFeignClient().insert(t);
    }

    /**
     * 通用的查一条数据方法
     *
     * @return 一条数据
     */
    @RequestMapping(value = "/query/{id}/{deviceId}", method = RequestMethod.GET)
    Result query(@PathVariable(name = "id") String id, @PathVariable(name = "deviceId") String deviceId) {
        log.info("通用的查一条数据方法,{}", id);
        return getBaseFeignClient().query(id, deviceId);
    }

    /**
     * 通用的删除一条数据方法
     *
     * @return 删除一条数据
     */
    @RequestMapping(value = "/delete/{id}/{deviceId}", method = RequestMethod.GET)
    Result delete(@PathVariable(name = "id") String id, @PathVariable(name = "deviceId") String deviceId) {
        log.info("通用的删除一条数据方法,{},{}", id, deviceId);
        return getBaseFeignClient().delete(id, deviceId);
    }

    /**
     * 通用的修改一条数据方法
     *
     * @return 修改一条数据
     */

    @RequestMapping(value = "/update/{id}/{deviceId}", method = RequestMethod.POST)
    Result update(@RequestBody T t, @PathVariable(name = "id") String id, @PathVariable(name = "deviceId") String deviceId) {
        log.info("通用的修改一条数据方法,{}", t);
        if (t == null) {
            return Result.fail(500, "request update body can not null!");
        }
        //校验
        Optional<Result> validate = t.validate(ValidateType.UPDATE);
        if (validate.isPresent()) {
            return validate.get();
        }

        return getBaseFeignClient().update(t, id, deviceId);
    }

    /**
     * 通用查询数据列表的方法，含有分页的功能
     * 子类继承父类即可使用该方法
     * {
     * "pageSize":10,
     * "pageNum":1,
     * "conditions":[{"name":"account","value":"123456","method":"eq"}]
     * }
     *
     * @return 查询到的数据列表集合
     */

    @RequestMapping(value = "/queryList", method = RequestMethod.POST)
    public Result queryList(@RequestBody QueryListParam param) {
        log.info("通用查询数据列表的方法,{}", param);

        if (param == null) {
            return Result.fail(500, "request param body can not null!");
        }
        User user = userService.getLoginUser().get();

        if (null != user) {
            List<SqlCondition> conditions = param.getConditions();
            conditions.add(new SqlCondition("userId", user.getId(), SqlCondition.Conditions.EQ));

            if (!param.contains("createDate")) {
                conditions.add(new SqlCondition("createDate", "createDate", SqlCondition.Conditions.DESC));
            }
        }

        return getBaseFeignClient().queryList(param);
    }
}
